In [ ]:
# Identify necessary images to perform the following using only OPENCV library.
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
import os
from scipy.signal import wiener
image = cv.imread('/content/drive/MyDrive/Colab Notebooks/Advanced Data Analytics/lab-image.webp')
image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
plt.imshow(image)
plt.show
Out[ ]:
matplotlib.pyplot.show
def show(*args, **kwargs)
Display all open figures. Parameters ---------- block : bool, optional Whether to wait for all figures to be closed before returning. If `True` block and run the GUI main loop until all figure windows are closed. If `False` ensure that all figure windows are displayed and return immediately. In this case, you are responsible for ensuring that the event loop is running to have responsive figures. Defaults to True in non-interactive mode and to False in interactive mode (see `.pyplot.isinteractive`). See Also -------- ion : Enable interactive mode, which shows / updates the figure after every plotting command, so that calling ``show()`` is not necessary. ioff : Disable interactive mode. savefig : Save the figure to an image file instead of showing it on screen. Notes ----- **Saving figures to file and showing a window at the same time** If you want an image file as well as a user interface window, use `.pyplot.savefig` before `.pyplot.show`. At the end of (a blocking) ``show()`` the figure is closed and thus unregistered from pyplot. Calling `.pyplot.savefig` afterwards would save a new and thus empty figure. This limitation of command order does not apply if the show is non-blocking or if you keep a reference to the figure and use `.Figure.savefig`. **Auto-show in jupyter notebooks** The jupyter backends (activated via ``%matplotlib inline``, ``%matplotlib notebook``, or ``%matplotlib widget``), call ``show()`` at the end of every cell by default. Thus, you usually don't have to call it explicitly there.
In [ ]:
# Sharpen and Blur the input image using cv.filter2D() and display the output for any 5 user defined kernels.
# Sharpening kernel
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
# Blurring kernels
blur_kernel_1 = np.ones((5,5),np.float32)/25
blur_kernel_2 = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]]) / 16
blur_kernel_3 = np.ones((3,3),np.float32)/9
blur_kernel_4 = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
blur_kernel_5 = np.array([[1/9, 1/9, 1/9], [1/9, 1/9, 1/9], [1/9, 1/9, 1/9]])
sharpened_image = cv.filter2D(src=image, ddepth=-1, kernel=sharpen_kernel)
blurred_image_1 = cv.filter2D(src=image, ddepth=-1, kernel=blur_kernel_1)
blurred_image_2 = cv.filter2D(src=image, ddepth=-1, kernel=blur_kernel_2)
blurred_image_3 = cv.filter2D(src=image, ddepth=-1, kernel=blur_kernel_3)
blurred_image_4 = cv.filter2D(src=image, ddepth=-1, kernel=blur_kernel_4)
blurred_image_5 = cv.filter2D(src=image, ddepth=-1, kernel=blur_kernel_5)
In [ ]:
image = cv.imread('/content/drive/MyDrive/Colab Notebooks/Advanced Data Analytics/noisy-image.png')
plt.imshow(image)
plt.show
Out[ ]:
matplotlib.pyplot.show
def show(*args, **kwargs)
Display all open figures. Parameters ---------- block : bool, optional Whether to wait for all figures to be closed before returning. If `True` block and run the GUI main loop until all figure windows are closed. If `False` ensure that all figure windows are displayed and return immediately. In this case, you are responsible for ensuring that the event loop is running to have responsive figures. Defaults to True in non-interactive mode and to False in interactive mode (see `.pyplot.isinteractive`). See Also -------- ion : Enable interactive mode, which shows / updates the figure after every plotting command, so that calling ``show()`` is not necessary. ioff : Disable interactive mode. savefig : Save the figure to an image file instead of showing it on screen. Notes ----- **Saving figures to file and showing a window at the same time** If you want an image file as well as a user interface window, use `.pyplot.savefig` before `.pyplot.show`. At the end of (a blocking) ``show()`` the figure is closed and thus unregistered from pyplot. Calling `.pyplot.savefig` afterwards would save a new and thus empty figure. This limitation of command order does not apply if the show is non-blocking or if you keep a reference to the figure and use `.Figure.savefig`. **Auto-show in jupyter notebooks** The jupyter backends (activated via ``%matplotlib inline``, ``%matplotlib notebook``, or ``%matplotlib widget``), call ``show()`` at the end of every cell by default. Thus, you usually don't have to call it explicitly there.
In [ ]:
# Mean Filtering
mean_filtered_image = cv.blur(image, (5,5))
# Gaussian Filter
gaussian_filtered_image = cv.GaussianBlur(image, (5,5), 0)
# Sobel Filter
sobel_right_kernal = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
sobel_down_kernal = np.array([[-1,-2,-1],[0,0,0],[1,2,1]])
sobel_left_kernal = np.array([[1,0,-1],[2,0,-2],[1,0,-1]])
sobel_up_kernal = np.array([[1,2,1],[0,0,0],[-1,-2,-1]])
sobel_left_image = cv.filter2D(image,-1,sobel_left_kernal)
sobel_right_image = cv.filter2D(image,-1,sobel_right_kernal)
sobel_up_image = cv.filter2D(image,-1,sobel_up_kernal)
sobel_down_image = cv.filter2D(image,-1,sobel_down_kernal)
# Median Filter
median_filtered_image = cv.medianBlur(image, 5)
# Laplacian Filter
laplacian_filtered_image = cv.Laplacian(image, cv.CV_64F)
abs_laplacian = cv.convertScaleAbs(laplacian_filtered_image)
# Bilateral Filter
bilateral_filtered_image = cv.bilateralFilter(image, 9, 75, 75)
# Non-Local Means Filtering
dst = cv.fastNlMeansDenoisingColored(image, None, 10, 10, 7, 21)
# Other filtering techniques
# 1. Box Filter
box_filtered_image = cv.boxFilter(image, -1, (5,5))
# 2. Scharr Filter
scharrx_image = cv.Scharr(image, cv.CV_64F, 1, 0)
scharry_image = cv.Scharr(image, cv.CV_64F, 0, 1)
abs_scharrx = cv.convertScaleAbs(scharrx_image)
abs_scharry = cv.convertScaleAbs(scharry_image)
# 3. Adaptive Gaussian Thresholding (for grayscale images)
gray_image = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
adaptive_thresh_image = cv.adaptiveThreshold(gray_image, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 2)
In [ ]:
plt.figure(figsize=(20,30))
plt.subplot(5,3,1)
plt.imshow(mean_filtered_image)
plt.title('Mean Filtered Image')
plt.subplot(5,3,2)
plt.imshow(gaussian_filtered_image)
plt.title('Gaussian Filtered Image')
plt.subplot(5,3,3)
plt.imshow(sobel_left_image)
plt.title('sobel LEft image')
plt.subplot(5,3,4)
plt.imshow(sobel_up_image)
plt.title('Sobel Up Image')
plt.subplot(5,3,5)
plt.imshow(sobel_right_image)
plt.title('Sobel right image')
plt.subplot(5,3,6)
plt.imshow(sobel_down_image)
plt.title('Sobel down image')
plt.subplot(5,3,7)
plt.imshow(median_filtered_image)
plt.title('Median Filtered Image')
plt.subplot(5,3,8)
plt.imshow(abs_laplacian)
plt.title('Laplacian Filter')
plt.subplot(5,3,9)
plt.imshow(bilateral_filtered_image)
plt.title('Bilateral Filtered Image')
plt.subplot(5,3,10)
plt.imshow(dst)
plt.title('NLM Filter Image')
plt.subplot(5,3,11)
plt.imshow(box_filtered_image)
plt.title('Box Filtered Image')
plt.subplot(5,3,12)
plt.imshow(abs_scharrx)
plt.title('Scharr x Filter Image')
plt.subplot(5,3,13)
plt.imshow(abs_scharry)
plt.title('Scharr y Filter Image')
plt.subplot(5,3,14)
plt.imshow(adaptive_thresh_image)
plt.title('Adaptive Thresholding Image')
plt.show()
In [ ]:
!pip install scikit-image
Requirement already satisfied: scikit-image in /usr/local/lib/python3.10/dist-packages (0.23.2) Requirement already satisfied: numpy>=1.23 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (1.26.4) Requirement already satisfied: scipy>=1.9 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (1.13.1) Requirement already satisfied: networkx>=2.8 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (3.3) Requirement already satisfied: pillow>=9.1 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (9.4.0) Requirement already satisfied: imageio>=2.33 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (2.34.2) Requirement already satisfied: tifffile>=2022.8.12 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (2024.7.24) Requirement already satisfied: packaging>=21 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (24.1) Requirement already satisfied: lazy-loader>=0.4 in /usr/local/lib/python3.10/dist-packages (from scikit-image) (0.4)
In [ ]:
from skimage.metrics import structural_similarity as ssim, mean_squared_error
import numpy as np
# List of filtered images
filtered_images = [
("Mean Filter", mean_filtered_image),
("Gaussian Filter", gaussian_filtered_image),
("Sobel Left Filter", sobel_left_image),
("Sobel Right Filter", sobel_right_image),
("Sobel Up Filter", sobel_up_image),
("Sobel Down Filter", sobel_down_image),
("Median Filter", median_filtered_image),
("Laplacian Filter", abs_laplacian),
("Bilateral Filter", bilateral_filtered_image),
("Non-Local Means Filter", dst),
("Box Filter", box_filtered_image),
("Scharr X Filter", abs_scharrx),
("Scharr Y Filter", abs_scharry),
("Adaptive Gaussian Threshold", adaptive_thresh_image),
]
# Function to compute SSIM, MSE
def compute_metrics(image1, image2):
# Convert images to grayscale if they are not already
if len(image1.shape) == 3 and image1.shape[2] == 3:
image1_gray = cv.cvtColor(image1, cv.COLOR_BGR2GRAY)
else:
image1_gray = image1
if len(image2.shape) == 3 and image2.shape[2] == 3:
image2_gray = cv.cvtColor(image2, cv.COLOR_BGR2GRAY)
else:
image2_gray = image2
ssim_value = ssim(image1_gray, image2_gray)
mse_value = mean_squared_error(image1_gray, image2_gray)
return ssim_value, mse_value
# Compute SSIM and MSE for each filtered image
similarity_scores = {}
mse_scores = {}
for name, filtered_image in filtered_images:
ssim_score, mse_score = compute_metrics(image, filtered_image)
similarity_scores[name] = ssim_score
mse_scores[name] = mse_score
# Sort the similarity scores in descending order
sorted_similarity_scores = sorted(similarity_scores.items(), key=lambda item: item[1], reverse=True)
sorted_mse_scores = sorted(mse_scores.items(), key=lambda item: item[1])
# Display the sorted list of filters with their SSIM and MSE values
print("Filters sorted by similarity (SSIM) to the original image:")
for name, score in sorted_similarity_scores:
print(f"{name}: SSIM = {score:.4f}, MSE = {mse_scores[name]:.4f}")
# Identify the filter with the highest similarity
best_match = sorted_similarity_scores[0]
print(f"\nThe filter with the highest similarity is: {best_match[0]} with an SSIM of {best_match[1]:.4f}")
print("\nFilters sorted by dissimilarity (MSE) to the original image:")
for name, score in sorted_mse_scores:
print(f"{name}: MSE = {score:.4f}, SSIM = {similarity_scores[name]:.4f}")
Filters sorted by similarity (SSIM) to the original image: Bilateral Filter: SSIM = 0.7733, MSE = 108.0790 Gaussian Filter: SSIM = 0.5769, MSE = 255.6299 Non-Local Means Filter: SSIM = 0.5706, MSE = 191.3123 Median Filter: SSIM = 0.3879, MSE = 414.1358 Mean Filter: SSIM = 0.3806, MSE = 387.0354 Box Filter: SSIM = 0.3806, MSE = 387.0354 Adaptive Gaussian Threshold: SSIM = 0.2573, MSE = 13752.2860 Laplacian Filter: SSIM = 0.0126, MSE = 12653.3059 Sobel Down Filter: SSIM = 0.0115, MSE = 16395.9739 Sobel Up Filter: SSIM = 0.0114, MSE = 16300.5667 Sobel Left Filter: SSIM = 0.0112, MSE = 16453.9052 Sobel Right Filter: SSIM = 0.0103, MSE = 16409.5789 Scharr Y Filter: SSIM = -0.0010, MSE = 15442.2722 Scharr X Filter: SSIM = -0.0023, MSE = 15528.0601 The filter with the highest similarity is: Bilateral Filter with an SSIM of 0.7733 Filters sorted by dissimilarity (MSE) to the original image: Bilateral Filter: MSE = 108.0790, SSIM = 0.7733 Non-Local Means Filter: MSE = 191.3123, SSIM = 0.5706 Gaussian Filter: MSE = 255.6299, SSIM = 0.5769 Mean Filter: MSE = 387.0354, SSIM = 0.3806 Box Filter: MSE = 387.0354, SSIM = 0.3806 Median Filter: MSE = 414.1358, SSIM = 0.3879 Laplacian Filter: MSE = 12653.3059, SSIM = 0.0126 Adaptive Gaussian Threshold: MSE = 13752.2860, SSIM = 0.2573 Scharr Y Filter: MSE = 15442.2722, SSIM = -0.0010 Scharr X Filter: MSE = 15528.0601, SSIM = -0.0023 Sobel Up Filter: MSE = 16300.5667, SSIM = 0.0114 Sobel Down Filter: MSE = 16395.9739, SSIM = 0.0115 Sobel Right Filter: MSE = 16409.5789, SSIM = 0.0103 Sobel Left Filter: MSE = 16453.9052, SSIM = 0.0112
Comparison of Filters by Similarity (SSIM) and Dissimilarity (MSE)¶
The following tables list various image filters along with their Structural Similarity Index (SSIM) and Mean Squared Error (MSE) scores, which measure the similarity and dissimilarity of the filtered images to the original image, respectively.
Filters Sorted by Similarity (SSIM)¶
| Filter | SSIM | MSE |
|---|---|---|
| Bilateral Filter | 0.7733 | 108.0790 |
| Gaussian Filter | 0.5769 | 255.6299 |
| Non-Local Means Filter | 0.5706 | 191.3123 |
| Median Filter | 0.3879 | 414.1358 |
| Mean Filter | 0.3806 | 387.0354 |
| Box Filter | 0.3806 | 387.0354 |
| Adaptive Gaussian Threshold | 0.2573 | 13752.2860 |
| Laplacian Filter | 0.0126 | 12653.3059 |
| Sobel Down Filter | 0.0115 | 16395.9739 |
| Sobel Up Filter | 0.0114 | 16300.5667 |
| Sobel Left Filter | 0.0112 | 16453.9052 |
| Sobel Right Filter | 0.0103 | 16409.5789 |
| Scharr Y Filter | -0.0010 | 15442.2722 |
| Scharr X Filter | -0.0023 | 15528.0601 |
Filters Sorted by Dissimilarity (MSE)¶
| Filter | MSE | SSIM |
|---|---|---|
| Bilateral Filter | 108.0790 | 0.7733 |
| Non-Local Means Filter | 191.3123 | 0.5706 |
| Gaussian Filter | 255.6299 | 0.5769 |
| Mean Filter | 387.0354 | 0.3806 |
| Box Filter | 387.0354 | 0.3806 |
| Median Filter | 414.1358 | 0.3879 |
| Laplacian Filter | 12653.3059 | 0.0126 |
| Adaptive Gaussian Threshold | 13752.2860 | 0.2573 |
| Scharr Y Filter | 15442.2722 | -0.0010 |
| Scharr X Filter | 15528.0601 | -0.0023 |
| Sobel Up Filter | 16300.5667 | 0.0114 |
| Sobel Down Filter | 16395.9739 | 0.0115 |
| Sobel Right Filter | 16409.5789 | 0.0103 |
| Sobel Left Filter | 16453.9052 | 0.0112 |
Key Observations¶
Highest Similarity: Bilateral Filter
- The Bilateral Filter achieved the highest SSIM score of 0.7733 and the lowest MSE of 108.0790, indicating that it preserves the structural integrity of the original image while effectively smoothing it. This makes it an excellent choice for applications requiring noise reduction while maintaining edge sharpness.
Gaussian Filter and Non-Local Means Filter
- The Gaussian Filter and Non-Local Means Filter also performed well, with SSIM scores of 0.5769 and 0.5706, and MSE values of 255.6299 and 191.3123, respectively. These filters are good for general smoothing and noise reduction.
Moderate Performance: Median, Mean, and Box Filters
- The Median Filter, Mean Filter, and Box Filter showed moderate similarity scores around 0.38 and moderate MSE values around 387. These filters are useful for certain types of noise removal but may not preserve edges as well as the Bilateral Filter.
Low Similarity: Edge Detection Filters
- Filters like the Laplacian, Sobel, and Scharr Filters had very low SSIM scores and high MSE values, indicating low similarity to the original image. These filters are designed for edge detection and highlighting gradients rather than maintaining overall image structure.
Negative Scores: Scharr Filters
- The Scharr Filters even produced negative SSIM scores, which indicates a significant deviation from the original image structure. These filters are highly specialized for edge detection tasks.
Overall, the Bilateral Filter stands out as the best choice for maintaining the original image's structure while providing effective smoothing and noise reduction.